package com.youku.core.view.components
{
   import com.youku.utils.DropFrameTable;
   import com.youku.PlayerConfig;
   import com.youku.core.view.interfaces.IVideo;
   import com.youku.core.model.vo.VideoSegmentData;
   import flash.display.Sprite;
   import com.youku.core.view.events.BaseVideoEvent;
   import com.youku.utils.Log;
   import com.youku.P2PConfig;
   import com.youku.events.CoreEvent;
   import com.youku.events.ReportEvent;
   import flash.net.NetStream;
   import flash.utils.setTimeout;
   import com.youku.interfaces.IVideoSegmentStatus;
   import com.youku.data.VideoSegmentStatus;
   import com.youku.interfaces.IPlayerProxy;
   
   public class MultiNSCore extends BaseCore
   {
      
      public function MultiNSCore(param1:IPlayerProxy, param2:CoreBase) {
         super(param1,param2);
         _dfTable = new DropFrameTable();
      }
      
      private var _p2pError:Boolean = false;
      
      private var _isSendSpeedReport:Boolean = true;
      
      override public function init(param1:Number, param2:Number) : void {
         super.init(param1,param2);
         var _loc3_:int = _playListData.segArr?_playListData.segArr.length:0;
         _dfTable = new DropFrameTable(_loc3_);
         this._p2pError = false;
         this.createVideoList();
         this.reportVV();
      }
      
      public function reportVV() : void {
      }
      
      override public function reInit() : void {
         super.reInit();
         this.clearAndCreateVideos();
         this.createDFTable();
      }
      
      protected function clearAndCreateVideos() : void {
         var _loc1_:* = 0;
         while(_loc1_ < _videoArr.length)
         {
            closeVideo(_videoArr[_loc1_]);
            _videoArr[_loc1_] = null;
            _loc1_++;
         }
         _playListData = PlayerConfig.playListData;
         this.createVideoList();
      }
      
      protected function createDFTable() : void {
         _dfTable.clear();
         _dfTable = null;
         var _loc1_:int = _playListData.segArr?_playListData.segArr.length:0;
         _dfTable = new DropFrameTable(_loc1_);
      }
      
      override protected function getVideoByNum(param1:Number) : IVideo {
         return _videoArr[param1];
      }
      
      private function createVideoList() : void {
         var _loc2_:String = null;
         var _loc3_:Array = null;
         var _loc5_:IVideo = null;
         var _loc6_:VideoSegmentData = null;
         var _loc1_:* = 0;
         for(_loc2_ in _playListData.videoSegmentsDic)
         {
            if(_playListData.videoSegmentsDic[_loc2_].length > _loc1_)
            {
               _loc1_ = _playListData.videoSegmentsDic[_loc2_].length;
            }
         }
         _loc3_ = _playListData.segArr;
         if(!(_playListData.fileType == null) && !(_playListData.fileType == ""))
         {
            _loc3_ = _playListData.videoSegmentsDic[_playListData.fileType];
         }
         if(_loc3_ == null)
         {
            return;
         }
         _videoArr = [];
         var _loc4_:* = 0;
         while(_loc4_ < _loc1_)
         {
            _loc5_ = this.generateVideo();
            this.addChild(_loc5_ as Sprite);
            if(_loc4_ < _loc3_.length)
            {
               _loc6_ = _loc3_[_loc4_];
            }
            _loc5_.init(_loc6_,_loc4_);
            _loc5_.addEventListener(BaseVideoEvent.PLAY_START,onVideoPlayStart);
            _loc5_.addEventListener(BaseVideoEvent.PLAY_OVER,this.onVideoPlayOver);
            _loc5_.addEventListener(BaseVideoEvent.JUMP_PLAY,this.onVideoJumpPlay);
            _loc5_.addEventListener(BaseVideoEvent.CONNECT_START,onVideoConnectStart);
            _loc5_.addEventListener(BaseVideoEvent.CONNECT_DONE,onVideoConnectDone);
            _loc5_.addEventListener(BaseVideoEvent.LOAD_BUFFER_FULL,onVideoLoadBufferFull);
            _loc5_.addEventListener(BaseVideoEvent.GOT_METADATA,onVideoGotMetadata);
            _loc5_.addEventListener(BaseVideoEvent.PLAY_LOAD_ERROR,onVideoLoadError);
            _loc5_.addEventListener(BaseVideoEvent.PLAY_MIDDLE_ERROR,onVideoMiddleError);
            _loc5_.addEventListener(BaseVideoEvent.RTMP_FAIL_ERROR,onRTMPVideoFailError);
            _loc5_.addEventListener(BaseVideoEvent.EARLY_REQUEST_ERROR,onVideoEarlyRequestError);
            _loc5_.addEventListener(BaseVideoEvent.BUFFER_EMPTY,onVideoBufferEmpty);
            _loc5_.addEventListener(BaseVideoEvent.BUFFER_FULL,onVideoBufferFull);
            _loc5_.addEventListener(BaseVideoEvent.BUFFER_PERCENT,onVideoBufferPercent);
            _loc5_.addEventListener(BaseVideoEvent.P2P_ERROR,this.onVideoP2PError);
            _loc5_.addEventListener(BaseVideoEvent.INVALID_PLAY_EVENT,this.onVideoInvalidPlayEvent);
            _loc5_.addEventListener(BaseVideoEvent.DRM_BROWSER_NOT_SUPPORT,onDRMError);
            _videoArr.push(_loc5_);
            _loc4_++;
         }
         _currentPlayVideo = _videoArr[0];
         setVideoUrlArr();
      }
      
      private function generateVideo() : IVideo {
         var _loc1_:IVideo = null;
         if(PlayerConfig.isRTMP)
         {
            _loc1_ = new RTMPVideo();
            return _loc1_;
         }
         if(_playListData.drm)
         {
            _loc1_ = new DRMStreamVideo();
            return _loc1_;
         }
         var _loc2_:Boolean = _playerProxy.playerData.isIKuInstall;
         _loc1_ = new HTTPVideo();
         return _loc1_;
      }
      
      protected function get shouldUseSS() : Boolean {
         Log.log("Trace","MultiNSCore.shouldUseSS P2PConfig.isSSPlayer = " + P2PConfig.isSSPlayer + " isrunning = " + P2PConfig.isP2PRunning + " totaltime = " + _playListData.totalTime + "  _p2perror = " + this._p2pError);
         var _loc1_:Boolean = _playerProxy.playerData.isIKuInstall;
         if(!_loc1_ && (P2PConfig.isSSPlayer) && (P2PConfig.isP2PRunning) && !this._p2pError && _playListData.threeD == null)
         {
            return true;
         }
         return false;
      }
      
      protected function get shouldUseXNet() : Boolean {
         var _loc1_:Boolean = _playerProxy.playerData.isIKuInstall;
         if(!_loc1_ && (P2PConfig.isXNetPlayer) && (P2PConfig.isP2PRunning) && !this._p2pError && _playListData.threeD == null)
         {
            return true;
         }
         return false;
      }
      
      override protected function onVideoPlayOver(param1:BaseVideoEvent) : void {
         var _loc2_:* = NaN;
         _loc2_ = param1.data.num == null?0:param1.data.num;
         _currentVideoNum = _loc2_ + 1;
         _corebase.dispatchEvent(new CoreEvent(CoreEvent.SEND_DYNAMIC_REPORT,
            {
               "code":"3002",
               "number":_loc2_
            }));
         if(_currentVideoNum < _playListData.segArr.length)
         {
            this.playNv();
            _currentLoadingNum = _currentVideoNum;
         }
         else
         {
            this.checkRTMPClose(_currentPlayVideo);
            _currentLoadingNum = 0;
            _currentVideoNum = 0;
            _currentPlayVideo = _videoArr[0];
            _playOver = true;
            saveWatchingRecord(true);
            _corebase.dispatchEvent(new CoreEvent(CoreEvent.SEND_DYNAMIC_REPORT,
               {
                  "code":"3008",
                  "number":_loc2_
               }));
            _corebase.dispatchEvent(new CoreEvent(CoreEvent.PLAY_OVER));
         }
      }
      
      override protected function onVideoJumpPlay(param1:BaseVideoEvent) : void {
         var _loc2_:Number = param1.data.num == null?0:param1.data.num;
         _currentVideoNum = _loc2_;
         _currentPlayVideo = _videoArr[_currentVideoNum];
         _currentLoadingNum = _currentVideoNum;
         _corebase.dispatchEvent(new CoreEvent(CoreEvent.JUMP_PLAY));
      }
      
      override protected function onVideoInvalidPlayEvent(param1:BaseVideoEvent) : void {
         _playerProxy.dispatchEvent(new ReportEvent(ReportEvent.INVALID_PLAY_EVENT,param1.data));
      }
      
      override protected function onVideoP2PError(param1:BaseVideoEvent) : void {
         super.onVideoP2PError(param1);
         var _loc2_:String = param1.data == null?"":param1.data.error;
         _playerProxy.dispatchEvent(new ReportEvent(ReportEvent.P2P_SOCKET_FAIL,{"error":_loc2_}));
         P2PConfig.P2PStatus = P2PConfig.SOCKET_FAIL_ERROR;
         this._p2pError = true;
         this.restorePlay();
      }
      
      protected function restorePlay() : void {
         var _loc1_:* = NaN;
         Log.log("restorePlay","nstime = " + _nsTime + " playtime = " + _loc1_ + " " + _isWaitingLoad + " " + _isPause);
         _loc1_ = _nsTime;
         this.clearAndCreateVideos();
         this.createDFTable();
         this.volume = _storeVolume;
         if((_isWaitingLoad) || (_isPause))
         {
            playWaitLoad(_loc1_);
         }
         else
         {
            play(_loc1_);
         }
      }
      
      override protected function checkDownloadComplete() : void {
         var _loc1_:IVideo = _videoArr[_currentLoadingNum];
         if(_loc1_ != null)
         {
            if(_loc1_.bytesLoaded == _loc1_.bytesTotal && _loc1_.bytesLoaded > 1)
            {
               if(!_loc1_.code2002Sent && _loc1_.bytesLoaded < _loc1_.oldTotalSize)
               {
                  _corebase.dispatchEvent(new CoreEvent(CoreEvent.SEND_DYNAMIC_REPORT,
                     {
                        "code":"2002",
                        "number":_loc1_.num
                     }));
                  _loc1_.code2002Sent = true;
               }
               else if(!_loc1_.code3004Sent)
               {
                  _corebase.dispatchEvent(new CoreEvent(CoreEvent.SEND_DYNAMIC_REPORT,
                     {
                        "code":"3004",
                        "number":_loc1_.num
                     }));
                  _loc1_.code3004Sent = true;
                  saveDownloadSpeed(_loc1_.speed);
               }
               
            }
         }
      }
      
      override protected function checkContinueDownloading() : void {
         var _loc2_:* = NaN;
         var _loc3_:* = NaN;
         var _loc4_:* = NaN;
         var _loc5_:* = false;
         var _loc6_:* = NaN;
         var _loc1_:IVideo = _videoArr[_currentLoadingNum];
         if(_loc1_ == null)
         {
            return;
         }
         if((_loc1_.loadOver) || (PlayerConfig.isRTMP) && (_loc1_.rtmpLoadOver))
         {
            _loc2_ = 0;
            _loc3_ = 0;
            _loc4_ = 0.85;
            if(_currentPlayVideo != null)
            {
               _loc2_ = _currentPlayVideo.nsTime / _currentPlayVideo.totalTime;
               _loc6_ = (_currentPlayVideo.totalTime - 45) / _currentPlayVideo.totalTime;
               _loc3_ = _loc4_ < _loc6_?_loc4_:_loc6_;
            }
            _loc5_ = false;
            if(!PlayerConfig.isRTMP)
            {
               _loc5_ = _playerProxy.playerData.isIKuAllowPreload;
            }
            if(!_dragHold && (_currentLoadingNum == _currentVideoNum && !_loc5_ || (_loc5_)) && _currentLoadingNum < _playListData.segArr.length - 1 && (_loc2_ > _loc3_ || (_loc5_)))
            {
               this.loadNextVideo();
            }
         }
      }
      
      override protected function checkChangeVideo() : void {
         var _loc2_:NetStream = null;
         if(_currentPlayVideo == null)
         {
            return;
         }
         var _loc1_:Number = _currentVideoNum + 1;
         if(_loc1_ >= _playListData.segArr.length)
         {
            return;
         }
         if(_currentPlayVideo.nsTime + 1 > _currentPlayVideo.totalTime)
         {
            _loc2_ = _videoArr[_loc1_].ns;
            _vd.preShow(_loc2_);
         }
      }
      
      override protected function updateBytes() : void {
         var _loc3_:IVideo = null;
         var _loc1_:Number = 0;
         var _loc2_:* = 0;
         while(_loc2_ < _videoArr.length)
         {
            _loc3_ = _videoArr[_loc2_] as IVideo;
            _loc1_ = _loc1_ + _loc3_.bytesLoaded;
            _loc2_++;
         }
         _corebase.loadedBytes = _loc1_ + BaseVideo.CLOSE_BYTES + BaseVideo.BV_CLOSE_BYTES;
      }
      
      override protected function updateTime() : void {
         var _loc6_:IVideo = null;
         var _loc1_:* = 0;
         while(_loc1_ < _videoArr.length)
         {
            _loc6_ = _videoArr[_loc1_] as IVideo;
            _loc6_.updateStatus();
            _loc1_++;
         }
         var _loc2_:Number = 0;
         var _loc3_:Number = 0;
         var _loc4_:int = _currentVideoNum;
         _loc1_ = _currentVideoNum + 1;
         while(_loc1_ < _videoArr.length)
         {
            if(_loc1_ >= _videoArr.length)
            {
               break;
            }
            _loc4_ = _loc1_;
            _loc6_ = _videoArr[_loc1_] as IVideo;
            if(_loc6_.jumpT == 0 && (_loc6_.loadOver))
            {
               _loc1_++;
               continue;
            }
            break;
         }
         _loc1_ = 0;
         while(_loc1_ <= _loc4_)
         {
            _loc6_ = _videoArr[_loc1_] as IVideo;
            if(_loc6_)
            {
               if(_loc1_ < _currentVideoNum)
               {
                  _loc2_ = _loc2_ + _loc6_.totalTime;
               }
               else if(_loc1_ == _currentVideoNum)
               {
                  if(_currentPlayVideo.loadOver)
                  {
                     _loc2_ = _loc2_ + _loc6_.totalTime;
                  }
                  else
                  {
                     _loc2_ = _loc2_ + _loc6_.loadedTime;
                     break;
                  }
               }
               else if(_loc1_ > _currentVideoNum && _loc1_ < _loc4_)
               {
                  _loc2_ = _loc2_ + _loc6_.totalTime;
               }
               else if(_loc1_ == _loc4_)
               {
                  _loc2_ = _loc2_ + _loc6_.loadedTime;
               }
               
               
               
            }
            _loc1_++;
         }
         _loc1_ = 0;
         while(_loc1_ <= _currentVideoNum)
         {
            _loc6_ = _videoArr[_loc1_] as IVideo;
            if(_loc6_)
            {
               if(_loc1_ == _currentVideoNum)
               {
                  _loc3_ = _loc3_ + _loc6_.nsTime;
               }
               else
               {
                  _loc3_ = _loc3_ + _loc6_.totalTime;
               }
            }
            _loc1_++;
         }
         _loadedTime = _loc2_;
         _nsTime = _loc3_;
         if(PlayerConfig.isRTMP)
         {
            _loadedTime = _nsTime;
         }
         var _loc5_:CoreEvent = new CoreEvent(CoreEvent.PLAYING,
            {
               "loadedTime":_loadedTime,
               "nsTime":_nsTime
            });
         _corebase.dispatchEvent(_loc5_);
         _loc5_ = null;
      }
      
      override protected function updateDroppedFrame() : void {
         var _loc1_:Number = 0;
         if(_videoArr[_currentVideoNum])
         {
            _loc1_ = _videoArr[_currentVideoNum].droppedFrames;
         }
         _dfTable.update(_currentVideoNum,_loc1_);
      }
      
      private function checkRTMPClose(param1:IVideo) : void {
         if(PlayerConfig.isRTMP)
         {
            if(param1)
            {
               param1.close();
            }
         }
      }
      
      private function loadNextVideo() : void {
         var _loc1_:IVideo = null;
         if(_currentLoadingNum < _playListData.segArr.length - 1)
         {
            _loc1_ = _videoArr[_currentLoadingNum + 1] as IVideo;
            if(!_loc1_.preloadDone)
            {
               _loc1_.load();
               _currentLoadingNum = _currentLoadingNum + 1;
            }
         }
      }
      
      private function playNv() : void {
         if((_currentPlayVideo) && !(_currentPlayVideo == _videoArr[_currentVideoNum]))
         {
            _currentPlayVideo.pause();
            _preVideoNum = _currentPlayVideo.num;
            setTimeout(this.hideNv,50);
         }
         _currentPlayVideo = _videoArr[_currentVideoNum];
         if(_currentPlayVideo)
         {
            _currentPlayVideo.play();
         }
         _vd.changeShow();
      }
      
      private function hideNv() : void {
         if(_videoArr[_preVideoNum])
         {
            this.checkRTMPClose(_videoArr[_preVideoNum]);
         }
      }
      
      override public function seek(param1:Number) : void {
         _isWaitingLoad = false;
         this.innerSeek(param1,true);
         if(!_dragHold)
         {
            _currentPlayVideo.resume();
            _isPause = false;
            _corebase.dispatchEvent(new CoreEvent(CoreEvent.RESUME));
         }
      }
      
      override public function mockSeek(param1:Number) : void {
         _isWaitingLoad = false;
         this.innerSeek(param1,false);
      }
      
      override public function seekLoad(param1:Number) : void {
         _isWaitingLoad = true;
         this.innerSeek(param1,false,true);
      }
      
      private function innerSeek(param1:Number, param2:Boolean, param3:Boolean = false) : void {
         var _loc7_:* = false;
         var _loc8_:* = false;
         _playOver = false;
         if(param1 < 0)
         {
            param1 = 0;
         }
         if(param1 > _playListData.totalTime)
         {
            param1 = _playListData.totalTime;
         }
         var _loc4_:Object = this.findSeekPosition(param1);
         var _loc5_:Number = _loc4_.t;
         _currentVideoNum = _loc4_.n;
         var _loc6_:* = 0;
         while(_loc6_ < _videoArr.length)
         {
            if(_loc6_ != _currentVideoNum)
            {
               _loc7_ = _loc6_ < _currentVideoNum && !_videoArr[_loc6_].loadOver;
               _loc8_ = _loc6_ > _currentVideoNum && (_videoArr[_loc6_].isJump) && !_videoArr[_loc6_].loadOver;
               if((_loc7_) || (_loc8_))
               {
                  closeVideo(_videoArr[_loc6_],false);
               }
               else
               {
                  _videoArr[_loc6_].setToHead();
               }
               this.checkRTMPClose(_videoArr[_loc6_]);
            }
            _loc6_++;
         }
         _currentPlayVideo = _videoArr[_currentVideoNum];
         _currentLoadingNum = _currentVideoNum;
         if(param3)
         {
            _currentPlayVideo.seekLoad(_loc5_);
         }
         else if(param2)
         {
            _currentPlayVideo.seek(_loc5_);
         }
         else
         {
            _currentPlayVideo.mockSeek(_loc5_);
         }
         
         updateVideo();
         _corebase.dispatchEvent(new CoreEvent(CoreEvent.SEEK));
      }
      
      private function findSeekPosition(param1:Number) : Object {
         var _loc2_:Array = _playListData.timeArr;
         var _loc3_:Number = _loc2_[0];
         var _loc4_:Number = 0;
         var _loc5_:Number = 0;
         var _loc6_:* = 0;
         while(_loc6_ < _loc2_.length)
         {
            if(param1 <= _loc3_)
            {
               _loc5_ = _loc6_;
               _loc4_ = _loc2_[_loc6_] - (_loc3_ - param1);
               break;
            }
            if(_loc6_ < _loc2_.length - 1)
            {
               _loc3_ = _loc3_ + Number(_loc2_[_loc6_ + 1]);
            }
            _loc6_++;
         }
         var _loc7_:Object = {};
         _loc7_.n = _loc5_;
         _loc7_.t = _loc4_;
         return _loc7_;
      }
      
      override public function close() : void {
         var _loc1_:String = null;
         super.close();
         for(_loc1_ in _videoArr)
         {
            closeVideo(_videoArr[_loc1_]);
            _videoArr[_loc1_] = null;
         }
         _videoArr = [];
      }
      
      override public function set volume(param1:Number) : void {
         if(param1 < 0)
         {
            param1 = 0;
         }
         _storeVolume = param1;
         var _loc2_:* = 0;
         while(_loc2_ < _videoArr.length)
         {
            if(_videoArr[_loc2_] == _currentPlayVideo)
            {
               _videoArr[_loc2_].volume = param1;
            }
            else
            {
               _videoArr[_loc2_].defaultVolume = param1;
            }
            _loc2_++;
         }
      }
      
      override public function resetData() : void {
         var _loc2_:String = null;
         var _loc1_:Array = _playListData.videoSegmentsDic[_playListData.fileType];
         if(_loc1_ == null)
         {
            return;
         }
         _firstGetMetadata = true;
         for(_loc2_ in _videoArr)
         {
            _videoArr[_loc2_].resetData(_loc1_[_loc2_]);
         }
         setVideoUrlArr();
      }
      
      override public function jumpTail() : void {
         super.jumpTail();
         _corebase.dispatchEvent(new CoreEvent(CoreEvent.SEND_DYNAMIC_REPORT,
            {
               "code":"3008",
               "number":_currentPlayVideo.num
            }));
      }
      
      override public function getVideoSegmentStatus(param1:Number) : IVideoSegmentStatus {
         if(param1 < 0 || param1 >= _videoArr.length)
         {
            return null;
         }
         var _loc2_:IVideoSegmentStatus = new VideoSegmentStatus();
         var _loc3_:IVideo = _videoArr[param1] as IVideo;
         _loc2_.speed = _loc3_.speed;
         _loc2_.currSpeed = _loc3_.currSpeed;
         _loc2_.startTime = _loc3_.jumpT;
         _loc2_.loadedTime = _loc3_.loadedTime;
         _loc2_.nsTime = _loc3_.nsTime;
         _loc2_.fps = _loc3_.FPS;
         return _loc2_;
      }
      
      override public function get currentPlayVideo() : IVideo {
         return _currentPlayVideo;
      }
      
      override public function get currentLoadingNum() : Number {
         return _currentLoadingNum;
      }
      
      override public function get currentVideoNum() : Number {
         return _currentVideoNum;
      }
   }
}
